/* 
 * File:   RenCommand.cpp
 * Author: Bram
 * 
 * Created on January 23, 2013, 1:36 PM
 */


#include "RenCommand.h"
#include "Config.h"

RenCommand RenCommand::cInstance("REN");

RenCommand::RenCommand(const char* szID )
	: Command( szID )
{
}

RenCommand::RenCommand() : Command() {
    setName("REN");
}

RenCommand::~RenCommand() {
}

Command* RenCommand::createNew()
{
    RenCommand * cmd = new RenCommand();
    cmd->setName("REN");
    return cmd;
}

bool RenCommand::isValid()
{
    return ((getName().compare("REN") == 0) && (sizeParameters() > 1) && Command::isValid());
}

//hier ontvangt de server het commando van de client
void RenCommand::ExcecuteServerReceiveCommand(TcpSocket* dasServer, queue<Command *>& commandQueue)
{
    cout << getName() << " COMMAND RECEIVED!" << endl;
    dasLog << getName() << " COMMAND RECEIVED!" << endl;
}

//hier komt de server nadat hij een bericht van de client heeft ontvangen met een dir request
//hij moet dus wat terug gaan sturen, hij past dus het huidigge commando aan en stuurt die op
void RenCommand::ExcecuteServerSendCommand(TcpSocket* dasServer, queue<Command *>& commandQueue)
{
    //moet minimaal 2 parameters zijn
    if(sizeParameters() > 1){ 
        
        string basePath;
        //string pathSEP = Config::getInstance()->PathSeparator;
        string fileToRename;
        string fileToRenameTO;
        string fullFileToRename;
        string fullFileToRenameTO;
        string fullFileToRenameTOdir;
        Config::getInstance()->getFullBasePath(basePath);
        
        getParameterAtIndex(0,fileToRename);
        getParameterAtIndex(1,fileToRenameTO);
        
        //locatie VAN de de te renamen file
        stringstream ssFR;
        ssFR << basePath << fileToRename;
        fullFileToRename = ssFR.str();
        
        //locatie waar de de te renamen file moet komen
        stringstream ssFRT;
        ssFRT << basePath << fileToRenameTO;
        fullFileToRenameTO = ssFRT.str();
        fullFileToRenameTOdir = ssFRT.str();
        
        //haalt de directory op van de file waar die moet komen
        Utility::getInstance()->FileToPath(fullFileToRenameTOdir, false);
        
        Utility::getInstance()->createDir(fullFileToRenameTOdir, basePath); //makt de betreffende dir
        
        if(Utility::getInstance()->fileExists(fullFileToRename)){
            int result = rename(fullFileToRename.c_str(), fullFileToRenameTO.c_str());
            if(result == 0){ //sih choed!
                addParameter(Config::getInstance()->OkRepresenter);
                //verwijderd alle lege mappen vanaf het basebath gezien, hoger opgelegen dus!
                Utility::getInstance()->removeEmptyFoldersInUpperPath(basePath);
            } else {
                addParameter("FAILLED");
            }
        } else {
            //folder not exists
            addParameter(Config::getInstance()->NotExistsRepresenter);
        }
    } else {
        // 0 parameters
        setName("ERROR");
        addParameter("ERROR DIR - ERROR in RenCommand.cpp - ExcecuteServerSendCommand(), failled on: if(sizeParameters() > 0){  - should not ever happen! 88887");
        cout << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', failled on: if(sizeParameters() > 0){  - should not ever happen! 88887" << endl;
        dasLog << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', failled on: if(sizeParameters() > 0){  - should not ever happen! 88887" << endl;
    }
    
    setType("END");
    
    //checkt of het command valide is
    if(!isValid()){
        clearParameters();
        stringstream ssERROR;
        ssERROR << "ERROR 3007 - ERROR BUILDING FULL COMMAND - NOT VALID: ";
        ssERROR << "name: '" << getName()  << "', ";
        ssERROR << "sender: '" << getSender()  << "', ";
        ssERROR << "type: '" << getType()  << "', ";
        addParameter(ssERROR.str());
        //bouwt eerst de error message en past daarna pas de message aan!
        setName("ERROR");
    }
    string totalCommandStr = buildFullCommand();
    if(totalCommandStr.size() > 10){
        dasServer->sendMessage(totalCommandStr);
        cout << "Server send successfully '" << getName() << "' message to client!" << endl;
        dasLog << "Server send successfully '" << getName() << "' message to client!" << endl;
    } else {
        cout << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', failled on: if(totalCommandStr.size() > 10){ - should not ever happen! 88888" << endl;
        dasLog << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', failled on: if(totalCommandStr.size() > 10){ - should not ever happen! 88888" << endl;
    }
}


//dit wordt uitgevoerd als de client het naar de server HEEFT VERSTUURD 
//en gaat wachten op een antwoord!
void RenCommand::ExcecuteClientReceiveCommand(TcpSocket* dasClient, queue<Command *>& commandQueue)
{
    if(!(getName().compare("ERROR") == 0) ){ //als het geen error is
        //haalt het volgende bericht op!
        Command * receivedCMD = getNextCommandFromSocket(dasClient);
        if(receivedCMD != 0){
            //als het GEEN error is
            if( !(receivedCMD->getName().compare("ERROR") == 0) ){ //als het geen error is
                //als het commando gelijk is aan het huidige commando!
                if(receivedCMD->getName().compare(getName()) == 0){
                    if(receivedCMD->sizeParameters() > 0){ 
                        cout << "****START " << receivedCMD->getName() << " COMMAND ****" << endl;
                        dasLog << "****START " << receivedCMD->getName() <<" COMMAND ****" << endl;
                        //de eerste parameter is de aanduiding of alles goed gegaan is!
                        string fileToRename;
                        string fileRenamedTo;
                        string returnMSG;
                        receivedCMD->getParameterAtIndex(0,fileToRename);
                        receivedCMD->getParameterAtIndex(1,fileRenamedTo);
                        receivedCMD->getParameterAtIndex(2,returnMSG);

                        if(returnMSG.compare(Config::getInstance()->OkRepresenter) == 0){
                            returnMSG = "SUCCEEDED";
                        } else if(returnMSG.compare(Config::getInstance()->NotExistsRepresenter) == 0){
                            returnMSG = "FAILLED - FILE NOT EXISTS";
                        } else {
                            returnMSG = "FAILLED - RENAMING FAILLED SOMEHOW";
                        }
                        cout << " * file: '" << fileToRename << "', renamed to: '" << fileRenamedTo << "', action: " << returnMSG << " * " << endl;
                        dasLog << " * file: '" << fileToRename << "', renamed to: '" << fileRenamedTo << "', action: " << returnMSG << " * " << endl;


                        //geeft de output terug
                        if(Clone(receivedCMD)){

                        }

                        cout << "****END " << receivedCMD->getName() << " COMMAND ****" << endl;
                        dasLog << "****END " << receivedCMD->getName() <<" COMMAND ****" << endl;
                    } else {
                        cout << getName() << " COMMAND FAILLED!!" << endl;
                        dasLog << getName() << " COMMAND FAILLED!!" << endl;
                        receivedCMD->PrintFullCout(); //debug!
                    }
                } else{
                    cout << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', curr cmd: '" << getName() << "', received cmd: '" << receivedCMD->getName() << "' - should not ever happen! 88886" << endl;
                    dasLog << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', curr cmd: '" << getName() << "', received cmd: '" << receivedCMD->getName() << "' - should not ever happen! 88886" << endl;
                }
            } else { //error
                stringstream ssERROR;
                for(int i = 0; i < receivedCMD->sizeParameters(); i++){
                    string strErr;
                    receivedCMD->getParameterAtIndex(0,strErr);
                    ssERROR << strErr << " - ";
                }
                string strTotalErr = ssERROR.str();
                cout << getName() << " COMMAND FAILLED! received error: " << strTotalErr << endl;
                dasLog << getName() << " COMMAND FAILLED! received error: " << strTotalErr << endl;
            }
        }

        receivedCMD = 0;
        delete receivedCMD;
    }
}
//dit wordt uitgevoerd als de client het ingetypte bericht naar de server verstuurd
void RenCommand::ExcecuteClientSendCommand(TcpSocket* dasClient, queue<Command *>& commandQueue)
{
    setType("END");
    //checkt of het command valide is
    if(!isValid()){
        clearParameters();
        stringstream ssERROR;
        ssERROR << "ERROR on sending '" << getName() << "' command to server! Command is nog valid! - ";
        ssERROR << "ERROR 3008 - ERROR BUILDING FULL COMMAND - NOT VALID: ";
        ssERROR << "name: '" << getName()  << "', ";
        ssERROR << "sender: '" << getSender()  << "', ";
        ssERROR << "type: '" << getType()  << "', ";
        cout << ssERROR.str() << endl;
        dasLog << ssERROR.str() << endl;
        
        clearParameters();
        addParameter(ssERROR.str());
        setName("ERROR");
        
        //@TODO huidigge command error van maken, dat komt dan naar voren in de client receive
    } else { //als alles goed is
        string totalCommandStr = buildFullCommand();
        if(totalCommandStr.size() > 10){
            dasClient->sendMessage(totalCommandStr);
        } else {
            stringstream ss;
            ss << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', if(totalCommandStr.size() > 10){ - should not ever happen! 88887" << endl;
            
            cout << ss.str();
            dasLog << ss.str();
            
            addParameter(ss.str());
            setName("ERROR");
        }
    }
}



